package com.java8.optional;

import com.java8.lambda.bean.Employee;
import org.junit.Test;

import java.util.Optional;

/**
 * @author xuehu
 * @date 2020/12/1 16:43
 */

public class TestOptionalCSDN {


    /**
     * Optional容器类
     * Optional<T> 类(java.util.Optional)是一个容器类，代表一个值存在或不存在，原来用null表示一个值不存在,现在Optional可以更好的表达这个概念。
     * 并且可以避免空指针异常。
     */
    //常用方法如下:

    /**
     * 1.Optional.of(T t) : 创建一个Optional实例
     *
     * 注意:使用Optional.of()创建Optional实例的时候不能传入null,否则会报空指针异常,也就是说如果使用Optional.of()出现空指针异常时
     * 通常都是传入的实参为null导致的，借助这个特点可以快速锁定空指针异常的位置。
     *
     */
    @Test
    public void test1() {
        Optional<Employee> employee = Optional.of(new Employee());
        System.out.println(employee);
    }

    /**
     * 2.Optional.empty(): 创建一个空的Optional实例
     * 注意:一旦Optional容器empty时再调用其get(),就会报NoSuchElementException异常
     */
    @Test
    public void test2() {
        Optional<Object> empyty = Optional.empty();
        System.out.println(empyty.get()); //报错java.util.NoSuchElementException: No value present
    }

    /**
     * 3.Optional.ofNullable(T t):若t不为null,创建Optional实例,否则创建空实例,该方法是of()和empty()的组合,
     * 如果为empty时调用get()会报异常NoSuchElementException
     */
    @Test
    public void test3() {
        Optional<Employee> employee = Optional.ofNullable(new Employee());
        System.out.println(employee.get());
    }

    /**
     * 4.isPresent():判断容器中是否包含值，用此方法可避免NoSuchElementException异常
     */
    @Test
    public void test4() {
        Optional<Object> objectOptional = Optional.ofNullable(null);
        if(objectOptional.isPresent()) {
            System.out.println(objectOptional.get());
        }
    }

    /**
     * 5.orElse(T t): 如果调用对象包含值,返回该值,否则返回t,此方法也可以避免出现空指针异常
     */
    @Test
    public void test5() {
        Optional<Object> optionalO = Optional.ofNullable(null);
        Object orElse = optionalO.orElse(new Employee("张三", 88, 8888888));
        System.out.println(orElse);
    }

    /**
     * 6.orElseGet(Supplier s): 如果调用对象包含值,返回该值,否则返回s获取的值,与orElse不同的是，这里返回的值是在函数中返回的
     * 可以有更多的逻辑判断具体返回哪个值
     */
    @Test
    public void test6() {
        Optional<Object> optionalO = Optional.ofNullable(null);
        Employee orElseGet = (Employee) optionalO.orElseGet(Employee::new);
        System.out.println(orElseGet);
    }

    /**
     * 7.map(Function f) : 如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty(),通过map将原容器中的类映射为新容器中的类型
     */
    @Test
    public void test7() {
        Optional<Employee> op = Optional.of(new Employee("张三", 88, 8888888));
        Optional<String> map = op.map(e -> e.getName());//通过map将原容器中的类映射为新容器中的类型
        System.out.println(map.get());
    }

    /**
     * 8.flatMap(Function mapper)：与 map 类似，但要求Function 的返回值必须是Optional类型，可实现流数据的扁平化等
     */
    @Test
    public void test8() {
        Optional<Employee> op = Optional.of(new Employee("张三", 88, 8888888));
        Optional<String> flatMap = op.flatMap((e) -> Optional.of(e.getName()));
        System.out.println(flatMap.get());
    }



}
